#include "DynamicArrayText.h"
#include <iostream>

DynamicArrayText::DynamicArrayText():size(0),capacity(30)//初始化列表  ？？为什么要加*free
{
    a = new ElementType[this->capacity];//指针指向一块新空间!符号是[]!
    
}

DynamicArrayText::~DynamicArrayText()
{
    
    delete []a;
}

DynamicArrayText::DynamicArrayText(const DynamicArrayText &d)
{
    this->size = d.size;
    this->capacity = d.capacity;
    this->a = new ElementType[this->capacity];
    for(int i = 0; i < this->size; i ++)//注意注意！数组传递值要使用for循环
    {
        a[i] = d.a[i];
    }
}

DynamicArrayText &DynamicArrayText::operator=(const DynamicArrayText &d)
{
    delete []a;
    this->size = d.size;
    this->capacity = d.capacity;
    this->a = new ElementType[this->capacity];
    for(int i = 0; i < this->size; i ++)//注意注意！数组传递值要使用for循环
    {
        a[i] = d.a[i];
    }
    return *this;
}

//扩容，是允许往小了扩的
void DynamicArrayText::Resize(int newcapacity)//newcapacity类似capacity
{
    
    this->size = size > newcapacity ? newcapacity : size;//确保新数组的大小不会超过预设的容量，同时也不会小于实际需要的容量。
    this->capacity = newcapacity;
    ElementType *newP = new ElementType[newcapacity];//开辟一块新的空间
    for(int i = 0 ; i < size; i++)
    {
        newP[i] = a[i];//将原数组值传递到新空间
    }
    delete []a;//释放原数组，不然会造成内存泄漏
    //和a = newP有区别吗
    this->a = newP;//当前指针指向新空间
}

//尾插法
void DynamicArrayText::InsertTail(ElementType element)
{
    //这里的size和capacity不都是this->a的嘛，为什么这样比较
    if(size >= capacity)//首先要判断空间够不够
        Resize(capacity * 2);//不够就要扩容
    this->a[size++] = element;//在下标size处插入元素
}

//头插法:是倒过来插入的
void DynamicArrayText::InsertHead(ElementType element)
{
    if(size >= capacity)//首先要判断空间够不够
        Resize(capacity * 2);
    for(int i = this->size; i >= 1; i--)//从最后一个元素开始，到a[0]->a[1]为止
    {
        a[i] = a[i - 1];//所有元素往后移了一位，给新元素留出空间
    }
    a[0] = element;//在a[0]处插入了元素
    size++;//插入一个，size要加一个
}

//中间插入
void DynamicArrayText::InsertByIndex(ElementType element, int index)
{
    if(index < 0 || index > size)//头插和尾插
    {
        std::cout<<"invalid index"<<std::endl;
        return;//直接报错返回
    }
    if(size >= capacity)//首先要判断空间够不够
        Resize(capacity * 2);
    for(int i = this->size; i > index; i--)//index本身及以后的元素往后移
    {
        a[i] = a[i - 1];
    }
    a[index] = element;
    size++;
}

//按位置删除
void DynamicArrayText::RemoveByIndex(int index)
{
    if(index < 0 || index > size)
    {
        std::cout<<"invalid index"<<std::endl;
        return;//直接报错返回
    }
    for(int i = index; i < size - 1; i++)//注意size-1
    {
        a[i] = a[i + 1];
    }
    size--;
}

//按值删除
void DynamicArrayText::RemoveByElement(ElementType element)
{
    for(int i = 0; i < size; i++)//一个个进行比较是否相等
    {
        if(a[i] == element)
        {
            RemoveByIndex(i);//直接调用按位置删除
            i--;//往前缩一个，对位置进行重新的判断
        }
    }
}

//按位置修改
void DynamicArrayText::UpDataByIndex(int index, ElementType newElement)
{
    if(index < 0 || index > size)
    {
        std::cout<<"invalid index"<<std::endl;
        return;//直接报错返回
    }
    a[index] = newElement;
}

//按值修改
void DynamicArrayText::UpDataByElement(ElementType oldValue, ElementType newValue)
{
    for(int i = 0; i < size; i++)//一个个进行比较是否相等
    {
        if(a[i] == oldValue)
        {
            a[i] = newValue;//修改不用动元素位置
        }
    }
}

//按位置查!
ElementType &DynamicArrayText::operator[](int index)
{
    return a[index];
}

//按值查
DynamicArrayText DynamicArrayText::FindByElement(ElementType element)
{
    DynamicArrayText result;//定义一个新的数组，因为可能有相同的数，要返回多个位置
    for(int i = 0; i < size; i ++)
    {
        if(a[i] == element)//找到相同的数值
        {
            result.InsertTail(i);//将数值的下标用尾插法插入result数组中
        }
    }
    return result;
}


std::ostream &operator<<(std::ostream &os, const DynamicArrayText &d)
{
    os<<"size:"<<d.size<<" capacity:"<<d.capacity<<std::endl;
    for(int i = 0; i < d.size; i++)//输出数组用for循环
    {
        os<<d.a[i]<<" ";
    }
    os<<std::endl;
    return os;
}
